<template>
  <transition appear name="slide-fade">
    <div class="list-container">
      <header class="header">
        <h1 class="heading">排行榜</h1>
      </header>
      <div class="content">
        <nav>
          <button
            :class="{ active: rankingType === 'personal' }"
            @click="rankingType = 'personal'"
          >
            个人
          </button>
        </nav>
        <div class="top-list">
          <div
            class="top-list-box"
            v-for="item in rankingList.slice(0, 3)"
            :key="item.userId"
          >
            <p
              class="user-name"
              style="margin: 0 0 20px 0"
              v-if="rankingType === 'personal'"
            >
              {{ item.username }}
            </p>
            <p class="score">{{ item.score.toFixed(0) }}分</p>
          </div>
        </div>
        <div class="list">
          <div
            class="list-box"
            v-for="(item, index) in rankingList.slice(3)"
            :key="item.userId"
            :class="{
              active:
                (rankingType === 'personal' && item.userId === userId) ||
                (rankingType !== 'personal' && item.teamId === userTeamId),
            }"
          >
            <span class="rank">{{ index + 4 }}</span>
            <div class="user-name" v-if="rankingType === 'personal'">
              {{ `${item.username}` }}
            </div>
            <div class="score">{{ item.score.toFixed(0) }}分</div>
          </div>
        </div>
        <div class="self list">
          <div class="list-box" v-if="me.rank !== 0">
            <span class="rank">{{ me.rank }}</span>
            <div class="user-name">{{ me.name }}</div>
            <div class="score" @click.self="showCertificate">
              {{ me.score.toFixed(0) }}分
            </div>
          </div>
        </div>
      </div>
    </div>
  </transition>
</template>

<script>
import { mapState, mapMutations } from "vuex";
import { GET_USER_INFO } from "@/store/mutation-types";
import { personalRank, teamRank } from "@/api";
import { encode } from "js-base64";

const getMe = (compareFn, genName) => (rankingList) => {
  if (!Array.isArray(rankingList)) {
    return {
      name: "Whoami",
      rank: 0,
      score: 666,
    };
  }
  const index = rankingList.findIndex(compareFn);
  if (index >= 0) {
    const me = rankingList[index];
    return {
      name: genName(me),
      username: me.username ?? "",
      teamName: me.team_name === "无" ? "" : me.team_name,
      score: me.score,
      rank: index + 1,
    };
  }
  return {
    name: "Whoami",
    rank: 0,
    score: 100,
  };
};

export default {
  name: "RankView",
  data() {
    return {
      rankingType: "personal", // 排行榜类别，team或者personal
      rankingList: [],
      me: {
        name: "Whoami",
        rank: 0,
        score: 100,
      },
    };
  },
  computed: mapState(["username", "token", "userId", "userTeamId"]),
  watch: {
    rankingType() {
      this.getList(this.rankingType);
    },
  },
  created() {
    this.getList(this.rankingType);
  },
  methods: {
    showCertificate() {
      const score = this.me.score.toFixed(0);
      this.$router.push({
        name: "certificate",
        query: {
          v: encode(JSON.stringify({ ...this.me, score })),
        },
      });
    },
    getList(type) {
      if (type === "personal") {
        personalRank()
          .then(({ data }) => {
            if (Array.isArray(data.rank)) {
              this.rankingList = data.rank;
            }
            return this.rankingList;
          })
          .then((list) => {
            this.me = getMe(
              ({ userId }) => userId === this.userId,
              // eslint-disable-next-line camelcase
              ({ username, team_name }) => `${username} (${team_name})`
            )(list);
          });
      } else {
        teamRank()
          .then(({ data }) => {
            if (Array.isArray(data.rank)) {
              // eslint-disable-next-line camelcase
              this.rankingList = data.rank.filter(
                ({ team_name }) => team_name !== "无"
              );
            }
            return this.rankingList;
          })
          .then((list) => {
            this.me = getMe(
              ({ teamId }) => teamId === this.userTeamId,
              // eslint-disable-next-line camelcase
              ({ team_name }) => team_name
            )(list);
          });
      }
    },
    ...mapMutations({
      getUserInfo: GET_USER_INFO,
    }),
  },
  mounted() {
    this.getUserInfo();
  },
};
</script>

<style lang="scss" scoped>
$themeColor: #d32f2f;

.slide-fade-enter-active,
.slide-fade-leave-active {
  transition: all 0.4s;
}
.slide-fade-enter,
.slide-fade-leave-to {
  transform: rotateY(45deg);
  opacity: 0;
}
.list-container {
  width: 100%;
  height: 100vh;
  background-color: $themeColor;
  font-weight: bold;
  .header {
    display: flex;
    align-items: center;
    width: 100%;
    height: 48px;
    .close-icon {
      position: absolute;
      top: 16px;
      left: 16px;
      width: 14px;
      height: 14px;
    }
    .heading {
      margin: 0 auto;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      font-size: 16px;
      font-weight: normal;
      color: #fff;
    }
  }
  .content {
    height: calc(100vh - 48px);
    overflow: auto;
    // 导航选项
    nav {
      display: flex;
      align-items: center;
      justify-content: space-around;
      button {
        width: 140px;
        height: 36px;
        border-radius: 18px;
        background-color: $themeColor;
        color: #fff;
        border: 2px solid #c49000;
        font-size: 14px;
        font-weight: bold;
        outline: none;
      }
      // 选中状态
      .active {
        background-color: #fbc02d;
        border-color: #fbc02d;
      }
    }
    // 前三名
    .top-list {
      display: flex;
      justify-content: space-around;
      align-items: flex-end;
      margin-bottom: 10px;
      width: 96%;
      margin-top: 60px;
      padding: 0 2%;
      .top-list-box {
        display: flex;
        flex-direction: column;
        align-items: center;
        color: #fff;
        position: relative;
        width: 32%;
        .avatar {
          margin-bottom: 40px;
          width: 56px;
          height: 56px;
          border-radius: 50%;
        }
        .user-name {
          width: 100%;
          font-size: 16px;
          text-align: center;
          word-break: keep-all;
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
        }
        .team-name {
          margin: 0 0 5px 0;
          font-size: 14px;
        }
        .score {
          display: flex;
          align-items: center;
          justify-content: center;
          margin: 0;
          padding: 0 8px;
          height: 30px;
          border-radius: 15px;
          background-color: #ff6659;
          font-size: 14px;
          letter-spacing: 0.1em;
        }
        &::before {
          content: "";
          position: absolute;
          bottom: 82px;
        }

        &:nth-child(1) {
          order: 2;
          .avatar {
            width: 76px;
            height: 76px;
          }
          &::before {
            //left: 20px;
            width: 50px;
            height: 50px;
            background: url("~@/assets/rank/first.svg") no-repeat center center;
            background-size: 50px 50px;
          }
        }

        &:nth-child(2) {
          order: 1;
          &::before {
            //left: 10px;
            width: 40px;
            height: 40px;
            background: url("~@/assets/rank/second.svg") no-repeat center center;
            background-size: 40px 40px;
          }
        }

        &:nth-child(3) {
          order: 3;
          &::before {
            //left: 10px;
            width: 40px;
            height: 40px;
            background: url("~@/assets/rank/third.svg") no-repeat center center;
            background-size: 40px 40px;
          }
        }
      }
    }
    // 其他名次排名
    .list {
      width: 100%;
      overflow: auto;
      .list-box {
        width: 92%;
        padding: 10px 4%;
        display: flex;
        align-items: center;
        justify-content: space-between;
        color: #fff;
        .rank {
          width: 36px;
          text-align: center;
        }
        .avatar {
          width: 32px;
          height: 32px;
          border-radius: 15px;
        }
        .user-name {
          width: calc(100% - 105px);
          text-align: left;
          font-size: 16px;
        }
        .score {
          display: flex;
          align-items: center;
          justify-content: center;
          padding: 0 8px;
          height: 30px;
          border-radius: 15px;
          background-color: #ff6659;
          font-size: 14px;
          letter-spacing: 0.1em;
        }
      }
      .active {
        background-color: #fbc02d;
      }
    }
    // 本人排名
    .self {
      position: absolute;
      bottom: 0;
      background-color: #fbc02d;
      padding: 0;
      .score {
        cursor: pointer;
      }
    }
  }
}
</style>
